package proxy.asm;

import com.fasterxml.jackson.databind.ObjectMapper;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.bytecode.SignatureAttribute;
import org.objectweb.asm.Opcodes;

import java.util.ArrayList;
import java.util.List;

/**
 * @auther hanchao
 * @date 2016/12/5 11:51
 */
public class Test2 extends ClassLoader implements Opcodes{
    public static void main(String[] args) throws Exception {
//        ParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
//        System.out.println(discoverer.getParameterNames(SayHello.class.getMethod("MethodE", List.class))[0]);
//        System.out.println(System.getProperty("java.version"));
        System.out.println(ISayHello.class.getMethod("MethodE", List.class).getGenericReturnType());
//        ClassPool cp =new ClassPool(true);
//        CtClass ctClass = cp.get("proxy.asm.Tests");//类全路径
//        ClassFile classFile = ctClass.getClassFile();
//        SignatureAttribute attribute = (SignatureAttribute)classFile.getAttribute("Signature");
//        System.out.println(attribute.getSignature());

        /*ClassPool cp =new ClassPool(true);
        CtClass ctClass = cp.get("proxy.asm.ISayHello");//类全路径
        ClassFile classFile = ctClass.getClassFile();*/


        ClassPool cp1 =new ClassPool();
        cp1.appendSystemPath();
        //  Lorg/springframework/core/ParameterizedTypeReference<Lcom/oglvip/business/dto/ResponseData<Lcom/oglvip/business/remote/service/entity/StoreAccount;>>;
        CtClass cc = cp1.makeClass("Test3",cp1.get("com.fasterxml.jackson.core.type.TypeReference"));
        //cc.setAttribute("Signature","(\"Lcom/fasterxml/jackson/core/type/TypeReference<Ljava/util/List<Ljava/lang/String;>;>;\");".getBytes());
        SignatureAttribute attribute = new SignatureAttribute(cc.getClassFile().getConstPool(),"Lcom/fasterxml/jackson/core/type/TypeReference<Ljava/util/List<Ljava/lang/String;>;>;");
        cc.setAttribute("Signature",attribute.get());
        cc.addConstructor(CtNewConstructor.make("public Test3(){super();}\n",cc));
        cc.addMethod(CtNewMethod.make("public void test(java.lang.String haha){}\n",cc));
        cc.writeFile("f:/");

        System.out.println("====");

        /*ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "Test", "Lcom/fasterxml/jackson/core/type/TypeReference<Ljava/util/List<Ljava/lang/String;>;>;",
                "com/fasterxml/jackson/core/type/TypeReference",null);

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
                null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "com/fasterxml/jackson/core/type/TypeReference", "<init>", "()V",false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        byte[] code = cw.toByteArray();
        FileOutputStream fos = new FileOutputStream("f:/Test.class");
        fos.write(code);
        fos.close();

        Class<?> exampleClass = new AsmClassLoader().defineClass("Test", cw.toByteArray());*/
        List<String> test = new ArrayList<String>();
        test.add("a");
        test.add("b");
        ObjectMapper mapper = new ObjectMapper();
        String s = mapper.writeValueAsString(test);
        System.out.println(s);

        //mapper.readValue(s,(TypeReference)cc.toClass().newInstance());
    }

    protected static class AsmClassLoader extends ClassLoader{
        public Class defineClass(String name, byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }
}
